package com.bocloud.cmp.service.resource;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bocloud.cmp.dao.BeanDetailDao;
import com.bocloud.cmp.dao.DataCenterDao;
import com.bocloud.cmp.dao.RackDao;
import com.bocloud.cmp.dao.RoomDao;
import com.bocloud.cmp.dao.ServerDao;
import com.bocloud.cmp.entity.resource.DataCenter;
import com.bocloud.cmp.entity.resource.Rack;
import com.bocloud.cmp.entity.resource.Room;
import com.bocloud.cmp.entity.resource.Server;
import com.bocloud.cmp.interfaces.resource.DataCenterService;
import com.bocloud.cmp.model.DataCenterBean;
import com.bocloud.cmp.service.utils.ParamHelper;
import com.bocloud.common.enums.BaseStatus;
import com.bocloud.common.model.BsmResult;
import com.bocloud.common.model.GridBean;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.Sign;
import com.bocloud.common.model.SimpleBean;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.coordinator.harmony.HarmonyLock;
import com.bocloud.coordinator.harmony.LockFactory;

/**
 * 数据中心抽象Service接口实现类
 * 
 * @author wei wei
 * @version 1.0
 * @since 2016.02.27
 */
@Service("dataCenterService")
public class DataCenterServiceImpl implements DataCenterService {

	private static Logger logger = LoggerFactory.getLogger(DataCenterServiceImpl.class);
	@Autowired
	private DataCenterDao dataCenterDao;
	@Autowired
	private RoomDao roomDao;
	@Autowired
	private RackDao rackDao;
	@Autowired
	private ServerDao serverDao;
	@Autowired
	private BeanDetailDao beanDetailDao;
	@Autowired
	private LockFactory lockFactory;

	@Override
	public BsmResult create(DataCenter dataCenter, Long userId) {
		try {
			dataCenter.setCreaterId(userId);
			dataCenter.setMenderId(userId);
			dataCenter.setStatus(BaseStatus.NORMAL.name());
			dataCenter.setUsed("0");
			dataCenterDao.save(dataCenter);
		} catch (Exception e) {
			logger.error("Create data center fail:", e);
			return new BsmResult(false, "添加失败", "", "");
		}
		return new BsmResult(true, dataCenter, "添加成功");
	}

	@Override
	public BsmResult modify(DataCenterBean bean, Long userId) {
		String path = DataCenter.class.getSimpleName() + "_" + bean.getId();
		HarmonyLock lock = null;
		try {
			Integer used = 0;
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时", "", "");
			}

			DataCenter center = this.dataCenterDao.query(bean.getId());
			if (null == center) {
				logger.warn("Data center does not exist!");
				return new BsmResult(false, "数据不存在", "", "");
			}

			if (StringUtils.isNotEmpty(center.getUsed())) {
				used = Integer.valueOf(center.getUsed());
			}
			if ((Integer.valueOf(bean.getTotalArea()) - used) < 0) {
				return new BsmResult(false, "数据中心面积不能小于已被使用的面积！");
			}
			BeanUtils.copyProperties(bean, center);
			center.setMenderId(userId);
			this.dataCenterDao.update(center);
			return new BsmResult(true, "修改成功");
		} catch (Exception e) {
			logger.error("Modify data center fail:", e);
			return new BsmResult(false, "修改失败", null, null);
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

	@Override
	public BsmResult remove(Long id, Long userId) {
		String path = DataCenter.class.getSimpleName() + "_" + id;
		int count = 0;
		HarmonyLock lock = null;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时", "", "");
			}

			DataCenter bean = this.beanDetailDao.getDCBean(id);
			if (null == bean) {
				logger.warn("Data center does not exist!");
				return new BsmResult(false, "数据不存在", "", "");
			}

			Map<String, Object> map = new HashMap<String, Object>();
			map.put(Common.DC, id);
			count = this.roomDao.count(ParamHelper.getParams(map, Sign.EQ));
			if (count > 0) {
				logger.warn("Remove fail：have rooms");
				return new BsmResult(false, "删除失败：该数据中心下存在机房，无法删除", "", "");
			}

			boolean result = this.dataCenterDao.remove(id, userId);
			if (result) {
				return new BsmResult(true, "删除成功");
			}
			logger.info("Data center has been deleted!");
			return new BsmResult(true, "已被删除");
		} catch (Exception e) {
			logger.error("Remove data center fail:", e);
			return new BsmResult(false, "删除失败", null, null);
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

	@Override
	public BsmResult basic(Long id) {
		DataCenter bean = null;
		try {
			bean = this.beanDetailDao.getDCBean(id);
			if (null == bean) {
				logger.warn("Data center does not exist!");
				return new BsmResult(false, bean, "该数据中心不存在");
			}
		} catch (Exception e) {
			logger.error("Query data center fail:", e);
			return new BsmResult(false, "查询失败", null, null);
		}
		return new BsmResult(true, bean, "查询成功");
	}

	@Override
	public BsmResult list(int page, int rows, List<Param> params, Map<String, String> sorter, Boolean simple) {
		List<DataCenter> list = null;
		List<SimpleBean> beans = null;
		int total = 0;
		GridBean gridBean = null;
		try {
			total = this.dataCenterDao.count(params);
			if (simple) {
				beans = this.dataCenterDao.list(params, sorter);
				gridBean = new GridBean(1, 1, total, beans);
			} else {
				list = this.dataCenterDao.list(page, rows, params, sorter);
				gridBean = GridHelper.getBean(page, rows, total, list);
			}
			return new BsmResult(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("Query data center list fail:", e);
			return new BsmResult(false, "查询失败", null, null);
		}
	}

	@Override
	public BsmResult listRooms(int page, int rows, List<Param> params, Map<String, String> sorter) {
		List<Room> list = null;
		int total = 0;
		GridBean gridBean = null;
		try {
			list = this.roomDao.list(page, rows, params, sorter);
			total = this.roomDao.count(params);
			gridBean = GridHelper.getBean(page, rows, total, list);
		} catch (Exception e) {
			logger.error("Query room list fail:", e);
			return new BsmResult(false, "查询失败", null, null);
		}
		return new BsmResult(true, gridBean, "查询成功");
	}

	@Override
	public BsmResult detail(Long id) {
		DataCenter center = null;
		try {
			if (id == 0) {
				center = new DataCenter();
				center.setCenters(this.dataCenterDao.count(null));
				center.setRooms(this.roomDao.count(null));
				center.setRacks(this.rackDao.count(null));
				center.setServers(this.serverDao.count(null));
			} else {
				center = this.beanDetailDao.getDCBean(id);
				if (null == center) {
					logger.warn("Data center does not exist!");
					return new BsmResult(false, center, "该数据中心不存在");
				}
				Map<String, Object> dcMap = new HashMap<String, Object>();
				dcMap.put(Common.DC, id);
				List<Room> roomList = this.roomDao.list(1, Integer.MAX_VALUE, ParamHelper.getParams(dcMap, Sign.EQ),
						null);
				List<Rack> rackList = new ArrayList<Rack>();
				int racks = 0;
				int servers = 0;
				if (null != roomList && !roomList.isEmpty()) {
					Map<String, Object> roomMap = new HashMap<String, Object>();
					for (Room room : roomList) {
						roomMap.put(Common.ROOM, room.getId());
						racks = racks + this.rackDao.count(ParamHelper.getParams(roomMap, Sign.EQ));
						rackList = this.rackDao.list(1, Integer.MAX_VALUE, ParamHelper.getParams(roomMap, Sign.EQ),
								null);
						if (null != rackList && !rackList.isEmpty()) {
							Map<String, Object> rackMap = new HashMap<String, Object>();
							for (Rack rack : rackList) {
								rackMap.put(Common.RACK, rack.getId());
								servers = servers + this.serverDao.count(ParamHelper.getParams(rackMap, Sign.EQ));
							}
						}
					}
				}
				dcMap.put(Common.DC, id);
				center.setRooms(this.roomDao.count(ParamHelper.getParams(dcMap, Sign.EQ)));
				center.setRacks(racks);
				center.setServers(servers);
			}
		} catch (Exception e) {
			logger.error("Query data center detail fail:", e);
			return new BsmResult(false, "查询失败", null, null);
		}
		return new BsmResult(true, center, "查询成功");
	}

	@Override
	public BsmResult freeNodes(Long id) {
		List<Server> list = null;
		try {
			list = this.serverDao.listFreeNode(id, DataCenter.class);
		} catch (Exception e) {
			logger.error("Query free server list from center fail:", e);
			return new BsmResult(false, "查询失败", null, null);
		}
		return new BsmResult(true, list, "查询成功");
	}

	@Override
	public BsmResult freeManagers(Long id) {
		List<Server> list = null;
		try {
			list = this.serverDao.listFreeManager(id, DataCenter.class);
		} catch (Exception e) {
			logger.error("Query free server list from center fail:", e);
			return new BsmResult(false, "查询失败", null, null);
		}
		return new BsmResult(true, list, "查询成功");
	}
}